require "albacore"
require "fileutils"
require "XmlSimple"
require_relative "Version"

nuspec :nuspec_patterns do |nuspec|
	nuspec.id = "Patterns"
	nuspec.title = "Code Patterns - Core Framework"
	nuspec.summary = "A high-level abstraction Api for general development acceleration"
	nuspec.description = "The Patterns package provides several abstraction layers on top of the CLR " + 
		"as well as several well-known open source projects such as Castle and AutoMapper. This package represents the core " + 
		"functionality needed by all other Patterns-related packages."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion => :nuspec_patterns do |nuspec|
	nuspec.id = "Patterns.Inversion"
	nuspec.title = "Code Patterns - Dependency Inversion"
	nuspec.summary = "A multi-provider abstraction Api for dependency inversion, component registration, and service location"
	nuspec.description = "The Patterns.Inversion package provides the core abstraction Api for dependency inversion. " + 
		"This package is required at a minimum if you want your Patterns-based application to support multi-provider IoC."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_web => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Web"
	nuspec.title = "Code Patterns - Web Framework"
	nuspec.summary = "A high-level abstraction Api for general web development acceleration"
	nuspec.description = "The Patterns.Web package provides web-based extensions to the foundation laid by " + 
		"the Patterns package."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion_autofac => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Inversion.Autofac"
	nuspec.title = "Code Patterns - Dependency Inversion - Autofac"
	nuspec.summary = "Autofac-specific extensions to the Dependency Inversion framework"
	nuspec.description = "The Patterns.Inversion.Autofac package provides the Autofac implementations " +
		"of the contracts defined in the Patterns.Inversion package."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion_castle => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Inversion.CastleWindsor"
	nuspec.title = "Code Patterns - Dependency Inversion - Castle Windsor"
	nuspec.summary = "Castle-specific extensions to the Dependency Inversion framework"
	nuspec.description = "The Patterns.Inversion.CastleWindsor package provides the Castle Windsor implementations " +
		"of the contracts defined in the Patterns.Inversion package."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion_linfu => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Inversion.LinFu"
	nuspec.title = "Code Patterns - Dependency Inversion - LinFu"
	nuspec.summary = "LinFu-specific extensions to the Dependency Inversion framework"
	nuspec.description = "The Patterns.Inversion.LinFu package provides the LinFu implementations " +
		"of the contracts defined in the Patterns.Inversion package."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion_mef => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Inversion.Mef"
	nuspec.title = "Code Patterns - Dependency Inversion - Mef"
	nuspec.summary = "Mef-specific extensions to the Dependency Inversion framework"
	nuspec.description = "The Patterns.Inversion.Mef package provides the Mef implementations " +
		"of the contracts defined in the Patterns.Inversion package."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion_ninject => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Inversion.Ninject"
	nuspec.title = "Code Patterns - Dependency Inversion - Ninject"
	nuspec.summary = "Ninject-specific extensions to the Dependency Inversion framework"
	nuspec.description = "The Patterns.Inversion.Ninject package provides the Ninject implementations " +
		"of the contracts defined in the Patterns.Inversion package."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion_spring => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Inversion.Spring"
	nuspec.title = "Code Patterns - Dependency Inversion - Spring"
	nuspec.summary = "Spring-specific extensions to the Dependency Inversion framework"
	nuspec.description = "The Patterns.Inversion.Spring package provides the Spring implementations " +
		"of the contracts defined in the Patterns.Inversion package."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion_structuremap => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Inversion.StructureMap"
	nuspec.title = "Code Patterns - Dependency Inversion - StructureMap"
	nuspec.summary = "StructureMap-specific extensions to the Dependency Inversion framework"
	nuspec.description = "The Patterns.Inversion.StructureMap package provides the StructureMap implementations " +
		"of the contracts defined in the Patterns.Inversion package."

	NuGet::initialize_nuspec(nuspec)
end

nuspec :nuspec_patterns_inversion_unity => [:nuspec_patterns, :nuspec_patterns_inversion] do |nuspec|
	nuspec.id = "Patterns.Inversion.Unity"
	nuspec.title = "Code Patterns - Dependency Inversion - Unity"
	nuspec.summary = "Unity-specific extensions to the Dependency Inversion framework"
	nuspec.description = "The Patterns.Inversion.Unity package provides the Unity implementations " +
		"of the contracts defined in the Patterns.Inversion package."

	NuGet::initialize_nuspec(nuspec)
end

task :nuspec_patterns_inversion_all => [
	:nuspec_patterns_inversion_autofac, 
	:nuspec_patterns_inversion_castle, 
	:nuspec_patterns_inversion_linfu, 
	:nuspec_patterns_inversion_mef,
	:nuspec_patterns_inversion_ninject,
	:nuspec_patterns_inversion_spring,
	:nuspec_patterns_inversion_structuremap,
	:nuspec_patterns_inversion_unity
]

class NuGet
	def self.initialize_nuspec(nuspec)
		base_source_path = File.join("..", "..", nuspec.id, "bin", "Debug", nuspec.id).gsub("/", "\\")
		dotnet_4 = File.join("lib", "NET40")

		nuspec.version = Version::current_version
		nuspec.authors = "John Batte"
		nuspec.language = "en-US"
		nuspec.licenseUrl = "http://www.gnu.org/licenses/gpl.html"
		nuspec.projectUrl = "http://code.google.com/p/new-tech-lab/wiki/PatternsOverview"
		nuspec.iconUrl = "http://cdn.battecode.com/images/projects/patterns/capital-p.png"
		nuspec.working_directory = File.expand_path(File.join(".nuget", "specs"))
		nuspec.file(base_source_path + ".dll", dotnet_4)
		nuspec.file(base_source_path + ".pdb", dotnet_4)
		nuspec.file(base_source_path + ".xml", dotnet_4)
		nuspec.output_file = nuspec.id + ".nuspec"

		load_dependencies!(nuspec)
		load_project_references!(nuspec)
	end

	def self.load_dependencies!(nuspec)
		path = File.join(nuspec.id, "packages.config")
		unless !File.exists? path
			data = XmlSimple.xml_in(path)
			data["package"].each do |package|
				if package["id"].include? "Patterns"
					nuspec.dependency(package["id"], Version::current_version)
				else
					nuspec.dependency(package["id"], package["version"])
				end
			end
		end
	end

	def self.load_project_references!(nuspec)
		path = File.join(nuspec.id, nuspec.id + ".csproj")
		project_ref_pattern = /(?<id>[^\\]+)\.csproj$/
		unless !File.exists? path
			data = XmlSimple.xml_in(path)
			data["ItemGroup"].each do |group|
				unless group["Reference"].nil?
					group["Reference"].each do |reference|
						if reference["Include"].include? "Patterns"
							nuspec.dependency(reference["Include"], Version::current_version)
						end
					end
				end
				unless group["ProjectReference"].nil?
					group["ProjectReference"].each do |project_ref|
						if project_ref["Include"].include? "Patterns"
							id = project_ref_pattern.match(project_ref["Include"])["id"]
							nuspec.dependency(id, Version::current_version)
						end
					end
				end
			end
		end
	end
end